package com.yiduo.outpost.core.web.exception;

import com.yiduo.outpost.core.model.exception.ErrorConstants;
import com.yiduo.outpost.core.model.exception.MethodArgumentNotValidField;
import com.yiduo.outpost.core.model.result.ResultCodeEnum;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yanwen
 */
public class MethodArgumentNotValidExceptionTranslator implements ExceptionTranslator {

    @Override
    public boolean support(Throwable error) {
        if (error instanceof MethodArgumentNotValidException) {
            FieldError fieldError = ((MethodArgumentNotValidException) error).getBindingResult().getFieldError();
            return fieldError != null && !StringUtils.isEmpty(fieldError.getDefaultMessage());
        }
        return false;
    }

    @Override
    public String translateException(Throwable error, MessageSource messageSource) {
        return messageSource.getMessage(ResultCodeEnum.BAD_REQUEST.getMessage(), null,ResultCodeEnum.BAD_REQUEST.getMessage(), LocaleContextHolder.getLocale());
    }

    public boolean supportFiled(Throwable error) {
        if (error instanceof MethodArgumentNotValidException) {
            FieldError fieldError = ((MethodArgumentNotValidException) error).getBindingResult().getFieldError();
            return fieldError != null && !StringUtils.isEmpty(fieldError.getField());
        }
        return false;
    }

    public Map<String, Object> translateExceptionFiled(Throwable error, MessageSource messageSource){
        Map<String, Object> map =  new  LinkedHashMap<>();
        List<FieldError> fieldErrors = ((MethodArgumentNotValidException) error).getBindingResult().getFieldErrors();
        List<MethodArgumentNotValidField> fields = fieldErrors.stream().map(fieldError -> {
            return new MethodArgumentNotValidField(fieldError.getField(), messageSource.getMessage(fieldError.getDefaultMessage(), null,fieldError.getDefaultMessage(), LocaleContextHolder.getLocale()));
        }).collect(Collectors.toList());
        map.put(ErrorConstants.ERROR_RESPONSE_REQUEST_CODE, ResultCodeEnum.BAD_REQUEST.getCode());
        map.put(ErrorConstants.ERROR_RESPONSE_REQUEST_FIELDS,fields);
        return map;
    }
}
